package com.gxa.weixing.portal.service.impl;

import com.gxa.weixing.core.common.ExceptionCode;
import com.gxa.weixing.core.exception.BusinessException;
import com.gxa.weixing.core.pojo.BalanceLog;
import com.gxa.weixing.core.pojo.GoldRecord;
import com.gxa.weixing.core.pojo.User;
import com.gxa.weixing.core.pojo.UserGold;
import com.gxa.weixing.core.service.impl.BaseServiceImpl;
import com.gxa.weixing.portal.mapper.*;
import com.gxa.weixing.portal.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.*;

/**
 * @Author ChenJ
 * @date 2022/01/05 18:14
 **/
@Service("userService")
@Transactional(rollbackFor = Throwable.class)
public class UserServiceImpl extends BaseServiceImpl<User> implements UserService {

    @Autowired
    private RedisTemplate<String,Object> redisTemplate;

    @Resource
    private UserMapper userMapper;

    @Resource
    private OrderMapper orderMapper;

    @Resource
    private UserGoldMapper userGoldMapper;

    @Resource
    private GoldRecordMapper goldRecordMapper;

    @Resource
    private ExchangeRecordMapper exchangeRecordMapper;

    @Resource
    private BalanceLogMapper balanceLogMapper;


    /**
     * 绑定安全手机号或者验证手机号
     *
     * @param phone 安全手机号
     * @param code  验证码
     * @param id    用户编号 如果存在则验证完手机号后将用户的安全手机号更换绑定为此手机号
     * @throws BusinessException
     */
    @Override
    public void bangDing(String phone, String code, Long id) throws BusinessException {
        // 获取redis上存储的验证码
        ValueOperations<String, Object> stringOps = redisTemplate.opsForValue();
        Object o = stringOps.get(SmsServiceImpl.VERIFY_SMS + phone);

        // 判断验证码是否失效
        if (o == null){
            throw new BusinessException(ExceptionCode.CODE_LOSE_EFFICACY);
        }

        // 将验证码转为字符串
        String redisCode = o.toString();

        // 校验验证码是否一致
        if (!redisCode.equals(code)){
            throw new BusinessException(ExceptionCode.CODE_WRONG);
        }

        // 验证完毕后删除redis上的缓存
        redisTemplate.delete(SmsServiceImpl.VERIFY_SMS+phone);

        // 如果是绑定手机号,先将用户信息查出,然后将安全安全手机号更改为最新验证过的手机号
        if (id!=null){
            User user = userMapper.selectByPrimaryKey(id);
            System.out.println(user+"-----------------------------------------");
            // 如果是第一次添加安全手机号,则可以领取首次设置安全手机号的任务金币奖励
            if (user.getSafePhone()==null){
                user.setHasGetFirstSafety(true);
            }
            user.setSafePhone(phone);
            int i = userMapper.updateByPrimaryKey(user);
        }

    }

    /**
     * 获取我的首页信息
     *
     * @param id
     * @return
     */
    @Override
    public Map<String, Object>  getMy(Long id){
        // 先根据id查到用户信息
        Map<String, Object> my = userMapper.getMy(id);
        // 再根据用户编号查询到用户的订单
        List<Map<String, Object>> payment = orderMapper.payment(id);
        List<Map<String, Object>> waitDeliver = orderMapper.waitDeliver(id);
        List<Map<String, Object>> waitReceiving = orderMapper.waitReceiving(id);
        List<Map<String, Object>> finished = orderMapper.finished(id);
        List<Map<String, Object>> refund = orderMapper.refund(id);
        my.put("payment",payment.size());
        my.put("waitDeliver",waitDeliver.size());
        my.put("waitReceiving",waitReceiving.size());
        my.put("finished",finished.size());
        my.put("refund",refund.size());
        // 根据用户编号查找金币数量
        BigDecimal usefulGold = userGoldMapper.getUsefulGold(id);
        // 如果没有金币则未0
        if (usefulGold==null){
            usefulGold = BigDecimal.valueOf(0L);
        }
        my.put("usefulGold",usefulGold);
        return my;
    }

    /**
     * 获取用户的金币记录
     *
     * @param id 用户编号
     * @return
     */
    @Override
    public Map<String, Object> getGoldRecord(Long id) {
        // 获取到用户的金币数量
        BigDecimal usefulGold = userGoldMapper.getUsefulGold(id);
        // 获取到用户的金币记录
        List<Map<String, Object>> goldRecord = goldRecordMapper.getGoldRecord(id);
        Map<String,Object> goldMap = new HashMap<>(16);
        goldMap.put("goldNum",usefulGold);
        goldMap.put("goldRecord",goldRecord);
        return goldMap;
    }

    /**
     * 获取用户的金币兑换记录
     *
     * @param id 用户编号
     * @param status 兑换状态
     * @return
     */
    @Override
    public List<Map<String, Object>> getExchangeRecord(Long id,Integer status) {
        List<Map<String, Object>> exchangeRecord = exchangeRecordMapper.getExchangeRecord(id,status);
        return exchangeRecord;
    }

    /**
     * 用户完成任务领取金币
     *
     * @param id 用户比那好
     * @return
     */
    @Override
    public void getGold(Long id,BigDecimal number) {
        UserGold userGold = userGoldMapper.getUserGold(id);
        BigDecimal number1 = userGold.getNumber();
        // 添加金币
        userGold.setNumber(number1.add(number));
        // 修改后数据持久化
        userGoldMapper.updateByPrimaryKey(userGold);
        GoldRecord goldRecord = new GoldRecord();
        goldRecord.setGoldId(userGold.getId());
        // 生成当前时间
        Date date = new Date(System.currentTimeMillis());
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        // 将当前时间往后延迟一年
        calendar.add(Calendar.YEAR,1);
        Date time = calendar.getTime();
        goldRecord.setExpirationTime(time);
        goldRecord.setOperating("完成任务");
        goldRecord.setNumber(number);
        goldRecord.setState(true);
        goldRecordMapper.insert(goldRecord);
    }

    /**
     * 获取用户余额提现记录
     *
     * @param id 用户编号
     * @return
     */
    @Override
    public List<Map<String, Object>> getBalanceLog(Long id) {
        List<Map<String, Object>> logList = balanceLogMapper.getLogList(id);
        return logList;
    }

    /**
     * 根据提现状态获取用户提现记录
     *
     * @param id     用户编号
     * @param status 提现状态
     * @return
     */
    @Override
    public List<Map<String, Object>> getBalanceLogByStatus(Long id, Integer status) {
        List<Map<String, Object>> balanceLogList = balanceLogMapper.getBalanceLogList(id, status);
        return balanceLogList;
    }

    /**
     * 用户提现
     *
     * @param id  用户编号
     * @param num 提现额度
     * @return
     */
    @Override
    public void withdraw(Long id, BigDecimal num) throws BusinessException {
        // 先根据用户编号获取用户
        User user = userMapper.selectByPrimaryKey(id);
        BigDecimal balance = user.getBalance();
        if (balance.compareTo(num)==-1){
            throw new BusinessException(ExceptionCode.NO_ENOUGH_MONEY);
        }
        user.setBalance(balance.subtract(num));
        // 将用户的余额减少
        userMapper.updateByPrimaryKey(user);

        BalanceLog balanceLog = new BalanceLog();
        // 设置为用户编号，关联用户
        balanceLog.setUserId(id);
        // 描述为提现金额
        balanceLog.setLogOperation("提现余额");
        // 提现金额
        balanceLog.setLogMoney(num);
        // 该记录为减少余额
        balanceLog.setLogOperationStatus(false);
        // 以当前时间为申请时间
        balanceLog.setLogApplyTime(new Date(System.currentTimeMillis()));
        // 订单号为当前时间戳加上一个随机数
        Date date = new Date(System.currentTimeMillis());
        long time = date.getTime();
        Random random = new Random();
        int i = random.nextInt(9);
        balanceLog.setLogOrder(time+""+i);
        // 审核中状态
        balanceLog.setLogStatus(0);
        // 操作类型为余额
        balanceLog.setBalanceOrGold(1);
        // 添加提现余额的记录
        balanceLogMapper.insert(balanceLog);
    }

}
